package com.aries.remoteplus.view;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.aries.remoteplus.R;
import com.aries.remoteplus.core.CommonFuncs;
import com.illposed.osc.OSCMessage;
import com.illposed.osc.OSCPortOut;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TableLayout;
import android.widget.TableRow;

public class KeyboardActivity extends Activity {

	private LinearLayout kbLinearLayout;
	private Map<String, Integer> keyCodeMap;
	private int lastRowNum;
	private OSCPortOut kbPortOut;
	private boolean isCtrlPressed;
	private boolean isShiftPressed;
	private boolean isWinPressed;
	private boolean isAltPressed;
	private boolean isCapsPressed;
	
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		
		this.isAltPressed 	= false;
		this.isCapsPressed 	= false;
		this.isCtrlPressed 	= false;
		this.isShiftPressed	= false;
		this.isWinPressed	= false;
		
		Intent dataIntent = this.getIntent();                   
		this.kbPortOut = CommonFuncs.getPortOutByIntent(dataIntent);
		
		this.initLayout();
		this.setContentView(this.kbLinearLayout);		
		
		
	}
	
	private void initLayout()
	{
		DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = null;
		InputStream inputStream = null;
		
		this.keyCodeMap = new HashMap<String, Integer>();
		
		int layoutFillParent 	= ViewGroup.LayoutParams.FILL_PARENT;
		
		this.kbLinearLayout = new LinearLayout(this);
		this.kbLinearLayout.setOrientation(LinearLayout.VERTICAL);
		this.kbLinearLayout.setLayoutParams(new LinearLayout.LayoutParams(layoutFillParent, layoutFillParent));
		
		TableLayout kbTableLayout = new TableLayout(this);
		kbTableLayout.setStretchAllColumns(true);
		kbTableLayout.setShrinkAllColumns(true);
		kbTableLayout.setLayoutParams(new LinearLayout.LayoutParams(layoutFillParent, layoutFillParent, 1.0f));
//		kbTableLayout.setBackgroundColor(0xff0f00ff);
		
		TableRow tableRow = new TableRow(this);
		tableRow.setLayoutParams(new TableLayout.LayoutParams(layoutFillParent, layoutFillParent, 1.0f));
//		tableRow.setBackgroundColor(0xffffffff);
		tableRow.setDuplicateParentStateEnabled(true);
		tableRow.setPadding(0, 0, 0, 0);
		
		try
		{
			builder 			= builderFactory.newDocumentBuilder();
			inputStream 		= this.getResources()
										.openRawResource(R.raw.keyboardmap);
			Document document 	= builder.parse(inputStream);
			Element root 		= document.getDocumentElement();
			NodeList keysList 	= root.getElementsByTagName("key");
			
			if (keysList != null)
			{
				this.lastRowNum = 0;
				for (int i = 0; i < keysList.getLength(); i++)
				{
					Node key = keysList.item(i);
					String keyText = key.getAttributes().getNamedItem("name").getNodeValue()
								.toString().toUpperCase();
					int keyCode = Integer.valueOf(key.getAttributes().getNamedItem("code")
											.getNodeValue().toString().substring(2), 16);
					int rowNum = Integer.parseInt(key.getAttributes().getNamedItem("row")
											.getNodeValue().toString());
					
					if (rowNum != this.lastRowNum)
					{
						kbTableLayout.addView(tableRow);
						
						this.kbLinearLayout.addView(kbTableLayout); 
												
						tableRow = new TableRow(this);
						tableRow.setLayoutParams(new TableLayout.LayoutParams(layoutFillParent, 
												layoutFillParent, 1.0f));
												
						kbTableLayout = new TableLayout(this);
						kbTableLayout.setStretchAllColumns(true);
						kbTableLayout.setShrinkAllColumns(true);
						kbTableLayout.setLayoutParams(new LinearLayout.LayoutParams(layoutFillParent, 
													layoutFillParent, 1.0f));
						
						this.lastRowNum = rowNum;
					}
					
					Button button = new Button(this);
					button.setText(keyText);	
					button.setOnClickListener(new ButtonClickListener());
					TableRow.LayoutParams btnLayoutParams = new TableRow.LayoutParams(layoutFillParent, layoutFillParent);
					btnLayoutParams.setMargins(2, 2, 2, 2);
					button.setLayoutParams(btnLayoutParams);
					button.setBackgroundResource(R.drawable.button_bg);
					tableRow.addView(button);
					
					keyCodeMap.put(keyText, keyCode);
				}
				kbTableLayout.addView(tableRow);
				this.kbLinearLayout.addView(kbTableLayout); 
			}
		} catch (FileNotFoundException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (DOMException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ParserConfigurationException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (inputStream != null)
			{
				try
				{
					inputStream.close();
				} catch (IOException e)
				{
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
	
	class ButtonClickListener implements OnClickListener
	{

		@Override
		public void onClick(View v)
		{
			// TODO Auto-generated method stub
			Button button = (Button) v;
			String btnText = button.getText().toString();
			int keyCode 	= keyCodeMap.get(btnText);		
			
			switch ( keyCode )
			{
				case 0x11:
				{
					//ctrl
					if ( !isCtrlPressed )
					{
						button.setBackgroundResource(android.R.drawable.button_onoff_indicator_on);
						isCtrlPressed = true;
					}
					else 
					{
						button.setBackgroundResource(android.R.drawable.button_onoff_indicator_off);
						isCtrlPressed = false;
					}
					Object[] args = new Object[]{keyCode, isCtrlPressed};
					sendKey(args);
					
					break;					
				}
					
				case 0x10:
				{
					//shift
					if ( !isShiftPressed )
					{
						button.setBackgroundResource(android.R.drawable.button_onoff_indicator_on);
						isShiftPressed = true;
					}
					else 
					{
						button.setBackgroundResource(android.R.drawable.button_onoff_indicator_off);
						isShiftPressed = false;
					}
					Object[] args = new Object[]{keyCode, isShiftPressed};
					sendKey(args);
					
					break;
				}
					
				case 0x020C:
				{
					//win
					if ( !isWinPressed )
					{
						button.setBackgroundResource(android.R.drawable.button_onoff_indicator_on);
						isWinPressed = true;
					}
					else 
					{
						button.setBackgroundResource(android.R.drawable.button_onoff_indicator_off);
						isWinPressed = false;
					}
					Object[] args = new Object[]{keyCode, isWinPressed};
					sendKey(args);
					
					break;
				}
					
				case 0x12:
				{
					//alt
					if ( !isAltPressed )
					{
						button.setBackgroundResource(android.R.drawable.button_onoff_indicator_on);
						isAltPressed= true;
					}
					else 
					{
						button.setBackgroundResource(android.R.drawable.button_onoff_indicator_off);
						isAltPressed = false;
					}
					Object[] args = new Object[]{keyCode, isAltPressed};
					sendKey(args);
					
					break;
				}
					
				case 0x14:
				{
					//caps
					if ( !isCapsPressed )
					{
						button.setBackgroundResource(android.R.drawable.button_onoff_indicator_on);
						isCapsPressed = true;
					}
					else 
					{
						button.setBackgroundResource(android.R.drawable.button_onoff_indicator_off);
						isCapsPressed = false;
					}
					Object[] args = new Object[]{keyCode, isCapsPressed};
					sendKey(args);
					
					break;
				}

				default:
				{
					Object[] args = new Object[]{keyCode};
					sendKey(args);
					break;
				}
			}
		}

	}
	
	private void sendKey(Object[] args)
	{
		OSCMessage message = new OSCMessage("/keyboard", args);
		
		try
		{
			this.kbPortOut.send(message);
		} catch (IOException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
